// typeof、 keyof、 in、 extends

// console.log(typeof 'hello')  // string

//  1, ts typeof 可用于提取类型
type TypeA = number | undefined;

let a: TypeA = 1

type TypeB = typeof a //定义变量类型

let TypeC = typeof a   // 'number'

console.log(TypeC)

//  2. keyof  作用获取某个类型的所有的key 返回值是联合类型
interface IPerson {
    name: string;
    age: number;
}

type PersonKey = keyof IPerson   //  'name' | 'age'

let b: PersonKey = 'name'


type PersonArrKey = keyof any[]  // 'at' | 'push'  .......,数组中所有的方法

let c: PersonArrKey = 'find'

type PromiseKey = keyof Promise<any> // 
let p: PromiseKey = 'catch'

// 更多的使用在泛型的类型参数中，用作类型的key的提取， 限制另外一种类型
function getValue<T, K extends keyof T>(obj: T, key: K) {
    return obj[key]
}

getValue([1, 2, 3, 4], 'length')  // 4

//  {a: number}
getValue({ a: 1 }, 'a')

// 3. in 运算符   in用来遍历联合类型
type TypeC = 'a' | 'b' | 'c';

type TypeD = {
    [propName in TypeC]: any
}

type TypeE<T> = {
    [p in keyof T]?: any
}

let objE: TypeE<{ num: number, value: string }> = {
    num: 10,
    value: 1
}


// 4. extends 泛型参数的限制

// 如果  extends 右边的类型是联合类型， extends左边的类型 只能是联合类型中的一项
function getValue1<T, K extends keyof T>(obj: T, key: K) {
    return obj[key]
}

// extends 右边的类型 是一个接口的情况

interface ITypeF {
    name: string
}

interface ITypeG {
    name: string,
    age: number
}

// 对于接口， extends左边的接口  要能包含（赋值给） 右边的接口  ，这时extends才能成立
function fn1<T, K extends T>(arg1: T, arg2: K) {

}

fn1<ITypeF, ITypeG>({ name: 'a' }, { name: 'b', age: 10 })


type arr = Promise<any>

export default null